﻿using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Resources;
using Mani.Common;

public partial class users : BasePage
{
    public override string ActionName {
        get {
            return "vw_users";
        }
    }

    protected void Page_Load(object sender, EventArgs e)
    {
        lblMessage.Visible = false;
        forUpdate.Visible = false;
        txtUserName.ReadOnly = false;
        txtEmail.ReadOnly = false;

        if (!Page.IsPostBack)
        {
            cblRoles.DataSource = Roles.GetAllRoles();
            cblRoles.DataBind();
            ShowUIMessages();

            if (!String.IsNullOrEmpty(Request.QueryString["mode"]))
                LoadUserForEdit();
        }
    }

    private void CreateUser()
    {
        MembershipCreateStatus status;
        MembershipUser NewUser = Membership.CreateUser(txtUserName.Text, txtPassword.Text, txtEmail.Text, null, null, checkIsApproved.Checked, out status);


        lblMessage.Visible = true;
        switch (status)
        {
            case MembershipCreateStatus.DuplicateEmail:
                lblMessage.Text = "آدرس ایمیل متعلق به کاربر دیگری می باشد";
                break;
            case MembershipCreateStatus.DuplicateProviderUserKey:
                lblMessage.Text = "کد خاص کاربر قبلا ثبت شده است";
                break;
            case MembershipCreateStatus.DuplicateUserName:
                lblMessage.Text = "شناسه کاربری قبلا رزرو شده است و مورد استفاده کاربر دیگری می باشد";
                break;
            case MembershipCreateStatus.InvalidAnswer:
                lblMessage.Text = "فرمت پاسخ سوال امنیتی اشتباه می باشد";
                break;
            case MembershipCreateStatus.InvalidEmail:
                lblMessage.Text = "فرمت ایمیل آدرس صحیح نمی باشد";
                break;
            case MembershipCreateStatus.InvalidPassword:
                lblMessage.Text = "فرمت رمز عبور صحیح نیست";
                break;
            case MembershipCreateStatus.InvalidProviderUserKey:
                lblMessage.Text = "فرمت کد خاص کاربر معتبر نمی باشد";
                break;
            case MembershipCreateStatus.InvalidQuestion:
                lblMessage.Text = "فرمت سوال امنیتی معتبر نیست";
                break;
            case MembershipCreateStatus.InvalidUserName:
                lblMessage.Text = "شناسه کاربری یافت نشد";
                break;
            case MembershipCreateStatus.ProviderError:
                lblMessage.Text = "سرویس شناسایی کاربران با خطا مواجه شده است";
                break;
            case MembershipCreateStatus.Success:
                lblMessage.Text = "عملیات مورد نظر با موفقیت انجام شد";
                break;
            case MembershipCreateStatus.UserRejected:
                lblMessage.Text = "به دلایل نامشخصی سرویس قادر به ایجاد کاربر نمی باشد";
                break;
            default:
                lblMessage.Text = "خطای نامشخص";
                break;
        }

        // add user to selected roles, update his/her profile and and clean up the form
        if (status == MembershipCreateStatus.Success)
        {
            for (int i = 0; i < cblRoles.Items.Count; i++)
                if (cblRoles.Items[i].Selected)
                    Roles.AddUserToRole(NewUser.UserName, cblRoles.Items[i].Text);

            ProfileCommon profile = Profile.GetProfile(NewUser.UserName);
            profile.UserFullName = txtFullName.Text;
            profile.Save();
            ResetForm("عملیات مورد نظر با موفقیت انجام شد");
        }
        gvMembership.DataBind();
    }

    private void EditUser()
    {
        string username = Request.QueryString["username"];
        MembershipUser user = Membership.GetUser(username);
        
        // change password if user changed password field
        if (!String.IsNullOrEmpty(txtPassword.Text))
        {
            // here we have to do a little hack here
            // we are using passwordFormat="Hashed" in web.config
            // because of one way hashing technique of Membership Provider
            // we can't retrieve user's old password so we have to reset it first in order to change it!
            user.ChangePassword(user.ResetPassword(), txtPassword.Text); 
        }

        // there is no way to lock someone
        // instead we must use isApproved property
        // only job we can do is unlock user if he already locked and admin unchecked isLock check box
        // TODO: Instead of using membership classes we could update database directly to solve this issue
        if (!checkIsLock.Checked)
            user.UnlockUser();

        user.IsApproved = checkIsApproved.Checked;
        user.Comment = txtComment.Text;
        ProfileCommon profile = Profile.GetProfile(user.UserName);
        profile.UserFullName = txtFullName.Text;
        profile.Save();
        Membership.UpdateUser(user);

        // update user's roles
        for (int i = 0; i < cblRoles.Items.Count; i++)
        {
            if (cblRoles.Items[i].Selected)
            {
                if (!Roles.IsUserInRole(user.UserName, cblRoles.Items[i].Text))
                    Roles.AddUserToRole(user.UserName, cblRoles.Items[i].Text);
            }
            else
            {
                if (Roles.IsUserInRole(user.UserName, cblRoles.Items[i].Text))
                    Roles.RemoveUserFromRole(user.UserName, cblRoles.Items[i].Text);
            }
        }

        ResetForm("عملیات مورد نظر با موفقیت انجام شد");
    }

    private void LoadUserForEdit()
    {
        forUpdate.Visible = true;
        txtUserName.ReadOnly = true;
        txtEmail.ReadOnly = true;

        string username = Request.QueryString["username"];
        MembershipUser user = Membership.GetUser(username);
        txtUserName.Text = username;
        txtEmail.Text = user.Email;
        lblCreateDate.Text = MyPersianDate.DateTimeToPersian(user.CreationDate);
        ProfileCommon profile = Profile.GetProfile(user.UserName);
        txtFullName.Text = profile.UserFullName;

        DateTime dt = Convert.ToDateTime("01/01/1754");
        if ( user.LastPasswordChangedDate.Date != dt)
            lblLastChangePass.Text = MyPersianDate.DateTimeToPersian(user.LastPasswordChangedDate);
        
        if ( user.LastLockoutDate.Date != dt )
            lblLastLock.Text = MyPersianDate.DateTimeToPersian(user.LastLockoutDate);

        if ( user.LastLoginDate.Date != dt )
            lblLastLogin.Text = MyPersianDate.DateTimeToPersian(user.LastLoginDate);

        checkIsApproved.Checked = user.IsApproved;
        checkIsLock.Checked = user.IsLockedOut;
        txtComment.Text = user.Comment;

        // load user's roles
        String[] UserRoles = Roles.GetRolesForUser(user.UserName);
        for (int i = 0; i < cblRoles.Items.Count; i++)
        {
            for (int m = 0; m < UserRoles.Length; m++)
            {
                if (UserRoles[m] == cblRoles.Items[i].Value)
                {
                    cblRoles.Items[i].Selected = true;
                }
            }
        }
    }

    protected void gvMembership_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        if (e.Row.RowType != DataControlRowType.DataRow)
            return;

        LinkButton lnkDelete = (LinkButton)e.Row.FindControl("DeleteUser");
        if (lnkDelete != null)
            lnkDelete.OnClientClick = @"return confirm('" + "آیا نسبت به حذف کاربر " +
                            e.Row.Cells[2].Text.Replace("'", "\'") + " مطمئن هستید ؟" +
                            "');";
    }

    protected void btnSubmit_Click(object sender, EventArgs e)
    {
        if (String.IsNullOrEmpty(Request.QueryString["mode"]))
            CreateUser();
        else if (Request.QueryString["mode"] == "edit")
            EditUser();

    }

    protected void btnReset_Click(object sender, EventArgs e)
    {
        ResetForm(null);
    }

    private void ResetForm(string message)
    {
        // it's more simple and robust solution than resetting all textboxes values
        // and setting lblMessage.Text in each function
        if ( String.IsNullOrEmpty(message ) )
            Response.Redirect("users.aspx", false);
        else
            Response.Redirect("users.aspx?message=" + message, false);
    }

    private void ShowUIMessages()
    {
        if (!String.IsNullOrEmpty(Request.QueryString["message"]))
        {
            lblMessage.Visible = true;
            lblMessage.Text = Request.QueryString["message"];
        }
    }
}
